﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace CodeContrib.Tasks
{
	public static class TaskExecutor
	{
		private static readonly ThreadLocal<List<Task>> _tasks = new ThreadLocal<List<Task>>(() => new List<Task>());

		public static Action<Exception> ExceptionHandler { get; set; }

		public static void Discard()
		{
			_tasks.Value.Clear();
		}

		public static void ExcuteLater(Task task)
		{
			_tasks.Value.Add(task);
		}

		public static void ExecuteNow(Task task)
		{
			for (var i = 0; i < 10; i++)
			{
				switch (task.Run())
				{
					case true:
					case false:
						return;
					case null:
						break;
				}
			}
		}

		public static void StartExecuting()
		{
			var tasks = _tasks.Value;
			var copy = _tasks.Value.ToArray();
			tasks.Clear();

			if (copy.Length > 0)
			{
				new TaskFactory().StartNew(() =>
					                           {
						                           foreach (var task in copy)
						                           {
							                           ExecuteNow(task);
						                           }
					                           }, TaskCreationOptions.LongRunning).ContinueWith(task =>
						                                                                            {
							                                                                            if (ExceptionHandler != null)
							                                                                            {
								                                                                            ExceptionHandler(task.Exception);
							                                                                            }
						                                                                            }, TaskContinuationOptions.OnlyOnFaulted);
			}
		}
	}
}